"""
Copyright 2022 NXP

SPDX-License-Identifier: Apache-2.0

The following demo shows how to display video in a window using Python.
"""

import cairo
import gi
import numpy as np
import sys

gi.require_version("Gtk", "3.0")
gi.require_version("Gst", "1.0")
gi.require_version('GLib', '2.0')
gi.require_version('GObject', '2.0')
from gi.repository import Gtk, Gst, Gio, Pango

VIDEO = "/dev/video3"
"""Change video source here"""


class SearchDialog(Gtk.Dialog):
    def __init__(self, parent):
        super().__init__(title="Search", transient_for=parent, modal=True)
        self.add_buttons(
            Gtk.STOCK_FIND,
            Gtk.ResponseType.OK,
            Gtk.STOCK_CANCEL,
            Gtk.ResponseType.CANCEL,
        )
        box = self.get_content_area()
        label = Gtk.Label(label="INSERT TEXT YOU WANT TO SEARCH FOR:")
        box.add(label)
        self.entry = Gtk.Entry()
        box.add(self.entry)
        self.show_all()


class VideoDemo(Gtk.Window):
    """A class that contains the UI and camera elements."""

    def __init__(self):
        """Create the UI and start the video feed."""
        # Create the UI window
        super().__init__()
        self.sample = None
        self.sample2 = None
        self.sample3 = None
        self.sample4 = None
        self.set_default_size(1600, 720)
        self.set_resizable(False)

        # create a notebook
        self.notebook = Gtk.Notebook()
        self.add(self.notebook)
        # create a Grid to attach button
        main_grid = Gtk.Grid(
            row_homogeneous=True, column_spacing=15, row_spacing=15)

        # Add fake controls
        gui_label = Gtk.Label.new("                             "
                                  "GUI can go here                      ")

        # Note that a lot of GTKs icon's are broken in our BSP. So I
        # create a custom header since the default one has broken icons
        header = Gtk.HeaderBar()
        header.set_title("Display Video Demo")
        header.set_subtitle("Video Demo")
        self.set_titlebar(header)

        # Button to quit
        quit_button = Gtk.Button()
        quit_icon = Gio.ThemedIcon(name="application-exit-symbolic")
        quit_image = Gtk.Image.new_from_gicon(quit_icon, Gtk.IconSize.BUTTON)
        quit_button.add(quit_image)
        header.pack_end(quit_button)
        quit_button.connect("clicked", Gtk.main_quit)

        # Button to click
        # Button grid
        grids = Gtk.Grid()
        button2 = Gtk.Button(label=" Run")
        button2.connect("clicked", self.button_clicked2)

        # Button to choose file
        button1 = Gtk.Button(label="choose file")
        button1.connect("clicked", self.on_file_clicked)

        # help
        button_help = Gtk.Button(label="HELP")
        button_help.connect("clicked", self.button_help_clicked)
        header.pack_end(button_help)
        header.pack_end(button1)
        header.pack_end(button2)
        button_close = Gtk.Button(label="CLOSE")
        button_close.connect("clicked", self.button_close_clicked)
        header.pack_end(button_close)

        # Area to display video
        self.draw_area = Gtk.DrawingArea.new()
        self.draw_area.set_hexpand(True)
        self.draw_area.set_vexpand(True)
        self.draw_area_1 = Gtk.DrawingArea.new()
        self.draw_area_1.set_hexpand(True)

        self.draw_area2 = Gtk.DrawingArea.new()
        self.draw_area2.set_hexpand(True)
        self.draw_area2.set_vexpand(True)
        self.draw_area_2 = Gtk.DrawingArea.new()
        self.draw_area_2.set_hexpand(True)

        self.draw_area3 = Gtk.DrawingArea.new()
        self.draw_area3.set_hexpand(True)
        self.draw_area3.set_vexpand(True)
        self.draw_area_3 = Gtk.DrawingArea.new()
        self.draw_area_3.set_hexpand(True)

        self.draw_area4 = Gtk.DrawingArea.new()
        self.draw_area4.set_hexpand(True)
        self.draw_area4.set_vexpand(True)
        self.draw_area_4 = Gtk.DrawingArea.new()
        self.draw_area_4.set_hexpand(True)

        # Tell GTK what function to use to draw
        self.draw_area.connect("draw", self.draw_cb)
        self.draw_area_1.connect("draw", self.draw_cb)
        self.draw_area2.connect("draw", self.draw_cb2)
        self.draw_area_2.connect("draw", self.draw_cb2)
        self.draw_area3.connect("draw", self.draw_cb3)
        self.draw_area_3.connect("draw", self.draw_cb3)
        self.draw_area4.connect("draw", self.draw_cb4)
        self.draw_area_4.connect("draw", self.draw_cb4)
        # Add video and label to window
        # main_grid.attach(gui_label, 0, 0, 1, 1)

        main_grid.attach(self.draw_area_1, 1, 0, 1, 1)
        self.create_textview(grids)
        self.create_buttons(grids)
        self.create_toolbar(grids)
        main_grid.attach(grids, 0, 0, 1, 1)

        main_grid2 = Gtk.Grid()
        grids2 = Gtk.Grid()
        self.create_textview2(grids2)
        main_grid2.attach(self.draw_area_2, 1, 0, 1, 1)
        main_grid2.attach(grids2, 0, 0, 1, 1)

        main_grid3 = Gtk.Grid()
        grids3 = Gtk.Grid()
        self.create_textview3(grids3)
        main_grid3.attach(self.draw_area_3, 1, 0, 1, 1)
        main_grid3.attach(grids3, 0, 0, 1, 1)

        main_grid4 = Gtk.Grid()
        grids4 = Gtk.Grid()
        self.create_textview4(grids4)
        main_grid4.attach(self.draw_area_4, 1, 0, 1, 1)
        main_grid4.attach(grids4, 0, 0, 1, 1)

        main_grid5 = Gtk.Grid()
        main_grid5.attach(self.draw_area, 1, 0, 1, 2)
        main_grid5.attach_next_to(self.draw_area2, self.draw_area, Gtk.PositionType.BOTTOM, 1, 2)
        main_grid5.attach_next_to(self.draw_area3, self.draw_area, Gtk.PositionType.RIGHT, 1, 2)
        main_grid5.attach_next_to(self.draw_area4, self.draw_area3, Gtk.PositionType.BOTTOM, 1, 2)

        self.notebook.append_page(main_grid5,Gtk.Label(label="main_title"))
        self.notebook.append_page(main_grid, Gtk.Label(label="palin title"))
        self.notebook.append_page(main_grid2, Gtk.Label(label="title2"))
        self.notebook.append_page(main_grid3, Gtk.Label(label="title3"))
        self.notebook.append_page(main_grid4, Gtk.Label(label="title4"))

        # GStreamer pipeline to use. Note that the format is in RGB16. I'm
        # not sure if this is the only format that can be used, but it seems
        # the most straight forward

        # Parse the above pipeline

        # cam_pipeline = "playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm"

        # self.pipeline = Gst.parse_launch(cam_pipeline)

        # Set a callback function to get the frame
        # tensor_sink = self.pipeline.get_by_name('sink')
        # tensor_sink.connect('new-sample', self.on_new_data)

        # Run the pipeline
        # self.pipeline.set_state(Gst.State.PLAYING)

    def on_new_data(self, element):
        """Get the new frame and signal a redraw."""
        # Get the new frame and save it
        self.sample = element.emit('pull-sample')
        # Notify the draw area to redraw itself
        self.draw_area.queue_draw()
        return 0

    def on_new_data2(self, element):
        self.sample2 = element.emit('pull-sample')
        self.draw_area2.queue_draw()
        return 0

    def on_new_data3(self, element):
        self.sample3 = element.emit('pull-sample')
        self.draw_area3.queue_draw()
        return 0

    def on_new_data4(self, element):
        self.sample4 = element.emit('pull-sample')
        self.draw_area4.queue_draw()
        return 0

    def draw_cb4(self, widget, context):
        if self.sample4 is None:
            context.set_source_rgb(0, 0, 0)
            context.paint()
            return
        buffer = self.sample4.get_buffer()
        caps4 = self.sample4.get_caps()
        ret, mem_buf = buffer.map(Gst.MapFlags.READ)
        height = caps4.get_structure(0).get_value("height")
        width = caps4.get_structure(0).get_value("width")
        frame = np.ndarray(
            shape=(height * width), dtype=np.uint16, buffer=mem_buf.data)
        frame = frame.copy()

        # Paint the new frame
        surface = cairo.ImageSurface.create_for_data(
            frame, cairo.Format.RGB16_565, width, height)
        context.set_source_surface(surface)
        context.paint()

        # Clean up
        buffer.unmap(mem_buf)

    def draw_cb3(self, widget, context):
        if self.sample3 is None:
            context.set_source_rgb(0, 0, 0)
            context.paint()
            return
        buffer = self.sample3.get_buffer()
        caps = self.sample3.get_caps()
        ret, mem_buf = buffer.map(Gst.MapFlags.READ)
        height = caps.get_structure(0).get_value("height")
        width = caps.get_structure(0).get_value("width")
        frame = np.ndarray(
            shape=(height * width), dtype=np.uint16, buffer=mem_buf.data)
        frame = frame.copy()

        # Paint the new frame
        surface = cairo.ImageSurface.create_for_data(
            frame, cairo.Format.RGB16_565, width, height)
        context.set_source_surface(surface)
        context.paint()

        # Clean up
        buffer.unmap(mem_buf)

    def draw_cb2(self, widget, context):
        if self.sample2 is None:
            context.set_source_rgb(0, 0, 0)
            context.paint()
            return
        buffer = self.sample2.get_buffer()
        caps = self.sample2.get_caps()
        ret, mem_buf = buffer.map(Gst.MapFlags.READ)
        height = caps.get_structure(0).get_value("height")
        width = caps.get_structure(0).get_value("width")
        frame = np.ndarray(
            shape=(height * width), dtype=np.uint16, buffer=mem_buf.data)
        frame = frame.copy()

        # Paint the new frame
        surface = cairo.ImageSurface.create_for_data(
            frame, cairo.Format.RGB16_565, width, height)
        context.set_source_surface(surface)
        context.paint()

        # Clean up
        buffer.unmap(mem_buf)

    def draw_cb(self, widget, context):
        """Draw the frame in the GUI."""
        # Protect against empty frames at the beginning
        # Draw a black background if there is nothing
        if self.sample is None:
            context.set_source_rgb(0, 0, 0)
            context.paint()
            return
        # Get frame details
        buffer = self.sample.get_buffer()
        caps = self.sample.get_caps()
        ret, mem_buf = buffer.map(Gst.MapFlags.READ)
        height = caps.get_structure(0).get_value("height")
        width = caps.get_structure(0).get_value("width")

        # While GStreamer provides a buffer, it is read only even if write
        # flags are set above. Cairo requires the buffer to be writable so the
        # two cannot interface with each other. The workaround is to use Numpy
        # to create a writable copy of the buffer.
        frame = np.ndarray(
            shape=(height * width), dtype=np.uint16, buffer=mem_buf.data)
        frame = frame.copy()

        # Paint the new frame
        surface = cairo.ImageSurface.create_for_data(
            frame, cairo.Format.RGB16_565, width, height)
        context.set_source_surface(surface)
        context.paint()

        # Clean up
        buffer.unmap(mem_buf)

    def button_close_clicked(self, widget):
        close_wins = Gtk.Window()
        close_grid = Gtk.Grid()

        close_button1 = Gtk.Button(label="CLOSE BUTTON 1")
        close_button1.connect("clicked", self.close_button_1)
        close_grid.add(close_button1)

        close_button2 = Gtk.Button(label="CLOSE BUTTON 2")
        close_button2.connect("clicked", self.close_button_2)
        close_grid.add(close_button2)

        close_button3 = Gtk.Button(label="CLOSE BUTTON 3")
        close_button3.connect("clicked", self.close_button_3)
        close_grid.add(close_button3)

        close_button4 = Gtk.Button(label="CLOSE BUTTON 4")
        close_button4.connect("clicked", self.close_button_4)
        close_grid.add(close_button4)

        close_wins.add(close_grid)
        close_wins.connect("destroy", Gtk.main_quit)
        close_wins.show_all()
        Gtk.main()

    def close_button_1(self, widget):
        self.pipeline.set_state(Gst.State.NULL)

    def close_button_2(self, widget):
        self.pipeline2.set_state(Gst.State.NULL)

    def close_button_3(self, widget):
        self.pipeline3.set_state(Gst.State.NULL)

    def close_button_4(self, widget):
        self.pipeline4.set_state(Gst.State.NULL)

    def on_file_clicked(self, widget):
        file_win = Gtk.Window()
        dialog = Gtk.FileChooserDialog(
            title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)

        dialog.add_buttons(
            Gtk.STOCK_CANCEL,
            Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN,
            Gtk.ResponseType.OK,
        )
        file_path = ""
        self.add_filters(dialog)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("open clicked")
            print("flie selected : " + dialog.get_filename())
            file_path = dialog.get_filename()
        elif response == Gtk.ResponseType.CANCEL:
            print("cannel clicked")
        dialog.destroy()
        file_win.set_title(file_path)
        with open(file_path, "r", encoding='UTF-8') as f:
            res = f.read()
        # print(res)
        # print(type(res))
        file_label = Gtk.Label()
        file_label.set_text(res)
        file_label.set_justify(Gtk.Justification.LEFT)
        file_win.add(file_label)
        file_win.connect("destroy", Gtk.main_quit)
        file_win.show_all()
        Gtk.main()

    def add_filters(self, dialog):
        filter_text = Gtk.FileFilter()
        filter_text.set_name("text files")
        filter_text.add_mime_type("text/plain")
        dialog.add_filter(filter_text)

        filter_py = Gtk.FileFilter()
        filter_py.set_name("Python files")
        filter_py.add_mime_type("text/x-python")
        dialog.add_filter(filter_py)

        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_mime_type("*")
        dialog.add_filter(filter_any)

    def on_folder_clicked(self, widget):
        file_wins = Gtk.Window()

        dialog = Gtk.FileChooserDialog(
            title="please choose a folder",
            parent=self,
            actions=Gtk.FileChooserAction.SELECT_FOLDER,
        )
        dialog.add_button(
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, "Select", Gtk.ResponseType.OK
        )
        dialog.set_default_size(800, 400)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("select clicked")
            print("folder selected: " + dialog.get_filename())
        elif response == Gtk.ResponseType.CANCEL:
            print("cannel clicked")
        dialog.destroy()
        file_wins.set_title("hello")
        file_quit_button = Gtk.Button()
        file_quit_icon = Gio.ThemedIcon(name="application-exit-symbolic")
        file_quit_image = Gtk.Image.new_from_gicon(file_quit_icon, Gtk.IconSize.BUTTON)
        file_quit_button.add(file_quit_image)
        win.add(file_quit_button)
        file_quit_button.connect("clicked", Gtk.main_quit)
        win.show_all()
        Gtk.main()

    def button_help_clicked(self, widget):
        win = Gtk.Window()
        win.set_title("help")
        win.set_default_size(720, 480)
        win.set_resizable(False)
        help_label = Gtk.Label.new("help can be here")
        win.add(help_label)

        help_quit_button = Gtk.Button()
        help_quit_icon = Gio.ThemedIcon(name="application-exit-symbolic")
        help_quit_image = Gtk.Image.new_from_gicon(help_quit_icon, Gtk.IconSize.BUTTON)
        help_quit_button.add(help_quit_image)
        win.add(help_quit_button)
        help_quit_button.connect("clicked", Gtk.main_quit)
        win.show_all()
        Gtk.main()

    def create_toolbar(self, grids):
        toolbar = Gtk.Toolbar()
        grids.attach(toolbar, 0, 0, 3, 1)

        button_bold = Gtk.ToolButton()
        button_bold.set_icon_name("format-text-bold-symbolic")
        toolbar.insert(button_bold, 0)

        button_italic = Gtk.ToolButton()
        button_italic.set_icon_name("format-text-italic-symbolic")
        toolbar.insert(button_italic, 1)

        button_underline = Gtk.ToolButton()
        button_underline.set_icon_name("format-text-underline-symbolic")
        toolbar.insert(button_underline, 2)

        button_bold.connect("clicked", self.on_button_clicked3, self.tag_bold)
        button_italic.connect("clicked", self.on_button_clicked3, self.tag_italic)
        button_underline.connect("clicked", self.on_button_clicked3, self.tag_underline)

        toolbar.insert(Gtk.SeparatorToolItem(), 3)

        radio_justifyleft = Gtk.RadioToolButton()
        radio_justifyleft.set_icon_name("format-justify-left-symbolic")
        toolbar.insert(radio_justifyleft, 4)

        radio_justifycenter = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
        radio_justifycenter.set_icon_name("format-justify-center-symbolic")
        toolbar.insert(radio_justifycenter, 5)

        radio_justifyright = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
        radio_justifyright.set_icon_name("format-justify-right-symbolic")
        toolbar.insert(radio_justifyright, 6)

        radio_justifyfill = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
        radio_justifyfill.set_icon_name("format-justify-fill-symbolic")
        toolbar.insert(radio_justifyfill, 7)

        radio_justifyleft.connect(
            "toggled", self.on_justify_toggled, Gtk.Justification.LEFT
        )
        radio_justifycenter.connect(
            "toggled", self.on_justify_toggled, Gtk.Justification.CENTER
        )
        radio_justifyright.connect(
            "toggled", self.on_justify_toggled, Gtk.Justification.RIGHT
        )
        radio_justifyfill.connect(
            "toggled", self.on_justify_toggled, Gtk.Justification.FILL
        )

        toolbar.insert(Gtk.SeparatorToolItem(), 8)

        button_clear = Gtk.ToolButton()
        button_clear.set_icon_name("edit-clear-symbolic")
        button_clear.connect("clicked", self.on_clear_clicked)
        toolbar.insert(button_clear, 9)

        toolbar.insert(Gtk.SeparatorToolItem(), 10)

        button_search = Gtk.ToolButton()
        button_search.set_icon_name("system-search-symbolic")
        button_search.connect("clicked", self.on_search_clicked)
        toolbar.insert(button_search, 11)

    def create_textview(self, grids):
        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        grids.attach(scrolledwindow, 0, 1, 3, 1)

        self.textview = Gtk.TextView()
        self.textbuffer = self.textview.get_buffer()
        scrolledwindow.add(self.textview)
        self.tag_bold = self.textbuffer.create_tag("bold", weight=Pango.Weight.BOLD)
        self.tag_italic = self.textbuffer.create_tag("italic", style=Pango.Style.ITALIC)
        self.tag_underline = self.textbuffer.create_tag(
            "underline", underline=Pango.Underline.SINGLE
        )
        self.tag_found = self.textbuffer.create_tag("found", background="yellow")

    def create_textview2(self, grids):
        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        grids.attach(scrolledwindow, 0, 1, 3, 1)

        self.textview2 = Gtk.TextView()
        self.textbuffer2 = self.textview2.get_buffer()
        scrolledwindow.add(self.textview2)
        self.tag_bold2 = self.textbuffer2.create_tag("bold2", weight=Pango.Weight.BOLD)
        self.tag_italic2 = self.textbuffer2.create_tag("italic2", style=Pango.Style.ITALIC)
        self.tag_underline2 = self.textbuffer2.create_tag(
            "underline2", underline=Pango.Underline.SINGLE
        )
        self.tag_found = self.textbuffer2.create_tag("found2", background="yellow")

    def create_textview3(self, grids):
        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        grids.attach(scrolledwindow, 0, 1, 3, 1)

        self.textview3 = Gtk.TextView()
        self.textbuffer3 = self.textview3.get_buffer()
        scrolledwindow.add(self.textview3)
        self.tag_bold3 = self.textbuffer3.create_tag("bold3", weight=Pango.Weight.BOLD)
        self.tag_italic3 = self.textbuffer3.create_tag("italic3", style=Pango.Style.ITALIC)
        self.tag_underline3 = self.textbuffer3.create_tag(
            "underline3", underline=Pango.Underline.SINGLE
        )
        self.tag_found = self.textbuffer3.create_tag("found3", background="yellow")

    def create_textview4(self, grids):
        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        grids.attach(scrolledwindow, 0, 1, 3, 1)

        self.textview4 = Gtk.TextView()
        self.textbuffer4 = self.textview4.get_buffer()
        scrolledwindow.add(self.textview4)
        self.tag_bold4 = self.textbuffer4.create_tag("bold4", weight=Pango.Weight.BOLD)
        self.tag_italic4 = self.textbuffer4.create_tag("italic4", style=Pango.Style.ITALIC)
        self.tag_underline4 = self.textbuffer4.create_tag(
            "underline4", underline=Pango.Underline.SINGLE
        )
        self.tag_found = self.textbuffer4.create_tag("found3", background="yellow")

    def create_buttons(self, grids):
        check_editable = Gtk.CheckButton(label="Editable")
        check_editable.set_active(True)
        check_editable.connect("toggled", self.on_editable_toggled)
        grids.attach(check_editable, 0, 2, 1, 1)

        check_cursor = Gtk.CheckButton(label="Cursor Visible")
        check_cursor.set_active(True)
        check_editable.connect("toggled", self.on_cursor_toggled)
        grids.attach_next_to(
            check_cursor, check_editable, Gtk.PositionType.RIGHT, 1, 1
        )

        radio_wrapnone = Gtk.RadioButton.new_with_label_from_widget(None, "No Wrapping")
        grids.attach(radio_wrapnone, 0, 3, 1, 1)

        radio_wrapchar = Gtk.RadioButton.new_with_label_from_widget(
            radio_wrapnone, "Character Wrapping"
        )
        grids.attach_next_to(
            radio_wrapchar, radio_wrapnone, Gtk.PositionType.RIGHT, 1, 1
        )

        radio_wrapword = Gtk.RadioButton.new_with_label_from_widget(
            radio_wrapnone, "Word Wrapping"
        )
        grids.attach_next_to(
            radio_wrapword, radio_wrapchar, Gtk.PositionType.RIGHT, 1, 1
        )

        radio_wrapnone.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.NONE)
        radio_wrapchar.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.CHAR)
        radio_wrapword.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.WORD)

    def on_button_clicked3(self, widget, tag):
        bounds = self.textbuffer.get_selection_bounds()
        if len(bounds) != 0:
            start, end = bounds
            self.textbuffer.apply_tag(tag, start, end)

    def on_clear_clicked(self, widget):
        start = self.textbuffer.get_start_iter()
        end = self.textbuffer.get_end_iter()
        self.textbuffer.remove_all_tags(start, end)

    def on_editable_toggled(self, widget):
        self.textview.set_editable(widget.get_active())

    def on_cursor_toggled(self, widget):
        self.textview.set_cursor_visible(widget.get_active())

    def on_wrap_toggled(self, widget, mode):
        self.textview.set_wrap_mode(mode)

    def on_justify_toggled(self, widget, justification):
        self.textview.set_justification(justification)

    def run_button1_clicked(self, widget):
        start = self.textbuffer.get_start_iter()
        end = self.textbuffer.get_end_iter()
        str = self.textbuffer.get_text(start, end, 1)
        cam_pipeline = ("v4l2src device=" + VIDEO + " ! imxvideoconvert_g2d "
                                                    " ! video/x-raw,format=RGB16,width=1280,height=720 ! "
                                                    "appsink emit-signals=true name=sink")
        self.pipeline = Gst.parse_launch(cam_pipeline)
        tensor_sink = self.pipeline.get_by_name('sink')
        tensor_sink.connect('new-sample', self.on_new_data)
        self.pipeline.set_state(Gst.State.PLAYING)
        print("read success")

    def run_button2_clicked(self, widget):
        start = self.textbuffer2.get_start_iter()
        end = self.textbuffer2.get_end_iter()
        str = self.textbuffer2.get_text(start, end, 1)
        cam_pipline2 = ("v4l2src device=" + VIDEO + " ! imxvideoconvert_g2d "
                                                    " ! video/x-raw,format=RGB16,width=1280,height=720 ! "
                                                    "appsink emit-signals=true name=sink")
        self.pipeline2 = Gst.parse_launch(cam_pipline2)
        tensor_sink = self.pipeline2.get_by_name('sink')
        tensor_sink.connect('new-sample', self.on_new_data2)
        self.pipeline2.set_state(Gst.State.PLAYING)
        print("read2 success")

    def run_button3_clicked(self, widget):
        start = self.textbuffer3.get_start_iter()
        end = self.textbuffer3.get_end_iter()
        str = self.textbuffer3.get_text(start, end, 1)
        cam_pipline3 = (str)
        cam_pipline3 = ("v4l2src device=" + VIDEO + " ! imxvideoconvert_g2d "
                                                    " ! video/x-raw,format=RGB16,width=1280,height=720 ! "
                                                    "appsink emit-signals=true name=sink")
        self.pipeline3 = Gst.parse_launch(cam_pipline3)
        tensor_sink = self.pipeline3.get_by_name('sink')
        tensor_sink.connect('new-sample', self.on_new_data3)
        self.pipeline3.set_state(Gst.State.PLAYING)
        print("read3 success")

    def run_button4_clicked(self, widget):
        start = self.textbuffer4.get_start_iter()
        end = self.textbuffer4.get_end_iter()
        str = self.textbuffer4.get_text(start, end, 1)
        cam_pipline4 = (str)
        cam_pipline4 = ("v4l2src device=" + VIDEO + " ! imxvideoconvert_g2d "
                                                    " ! video/x-raw,format=RGB16,width=1280,height=720 ! "
                                                    "appsink emit-signals=true name=sink")
        self.pipeline4 = Gst.parse_launch(cam_pipline4)
        tensor_sink = self.pipeline4.get_by_name('sink')
        tensor_sink.connect('new-sample', self.on_new_data4)
        self.pipeline4.set_state(Gst.State.PLAYING)
        print("read4 success")

    def on_search_clicked(self, widget):
        dialog = SearchDialog(self)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            cursor_mark = self.textbuffer.get_insert()
            start = self.textbuffer.get_iter_at_mark(cursor_mark)
            if start.get_offset() == self.textbuffer.get_char_count():
                start = self.textbuffer.get_start_iter()
            self.search_and_mark(dialog.entry.get_text(), start)
        dialog.destroy()

    def search_and_mark(self, text, start):
        end = self.textbuffer.get_end_iter()
        match = start.forward_search(text, 0, end)
        if match is not None:
            match_start, match_end = match
            self.textbuffer.apply_tag(self.tag_found, match_start, match_end)
            self.search_and_mark(text, match_end)

    def button_clicked2(self, widget):
        run_wins = Gtk.Window()

        run_grid = Gtk.Grid()
        run_button1 = Gtk.Button(label="RUN BUTTON 1")
        run_button1.connect("clicked", self.run_button1_clicked)
        run_grid.add(run_button1)

        run_button2 = Gtk.Button(label="RUN BUTTON 2")
        run_button2.connect("clicked", self.run_button2_clicked)
        run_grid.add(run_button2)

        run_button3 = Gtk.Button(label="RUN BUTTON 3")
        run_button3.connect("clicked", self.run_button3_clicked)
        run_grid.add(run_button3)

        run_button4 = Gtk.Button(label="RUN BUTTON 4")
        run_button4.connect("clicked", self.run_button4_clicked)
        run_grid.add(run_button4)
        run_wins.add(run_grid)
        run_wins.connect("destroy", Gtk.main_quit)
        run_wins.show_all()
        Gtk.main()


if __name__ == "__main__":
    # Start GStreamer engine
    Gst.init(None)
    # Display window
    window = VideoDemo()

    window.show_all()

    # Run GTK loop
    Gtk.main()